import java.net.*;
import java.io.*;

public class Pop3 {
	Socket sock;
	BufferedReader input;
	PrintWriter output;

	String welcome;
	String response;	
	boolean connected = false;

	public Pop3(String host) throws Pop3Exception {
		System.setProperty("line.separator", "\r\n");
		try {
			sock = new Socket(host, 110);
			input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
			output = new PrintWriter(sock.getOutputStream(), true);
		}
		catch(UnknownHostException e) {
			throw new Pop3Exception("Unknows host, " + e.getMessage());
		}
		catch (IOException e) {
			throw new Pop3Exception(e.getMessage());
		}
		welcome = getResp();
		connected = true;
	}

	// Send a command and get the response
	private String sendCmd(String cmd) throws Pop3Exception {
		output.println(cmd);
		return getResp();
	}

	// Get a response from the server, throw exception if the response doesn't start with "+OK".	
	protected String getResp() throws Pop3Exception {
		try {
			response = input.readLine();
		}
		catch(IOException e) {
			throw new Pop3Exception(e.getMessage());
		}
		if(!response.startsWith("+OK")) {
			throw new Pop3Exception(response);
		}
		return response;
	}

	protected String getWelcome() {
		return welcome;
	}

	protected String user(String user) throws Pop3Exception {
		return sendCmd("USER " + user);
	}

	protected String pass(String pass) throws Pop3Exception {
		return sendCmd("PASS " + pass);
	}

	protected int getMailCount() throws Pop3Exception {
		response = sendCmd("STAT");
		String [] s = response.split(" ");
		int mailCount = Integer.parseInt(s[1]);
		return mailCount;
	}

	protected String dele(int delMail) throws Pop3Exception {
		return sendCmd("DELE " + delMail);
	}

	protected void disconnect() throws Pop3Exception {
		output.close();
		try {
			input.close();
			sock.close();
			connected = true;
		}
		catch(IOException e) {
			return;
		}
	}

	protected void quit() throws Pop3Exception {
		sendCmd("QUIT");
		output.close();
		try {
			input.close();
			sock.close();
			connected = true;
		}
		catch(IOException e) {
			return;
		}
	}

	protected boolean isConnected() {
		return connected;
	}
}
